import java.net.MalformedURLException;
import java.net.URL;
import java.util.InputMismatchException;
import java.util.Scanner;
import java.util.concurrent.ConcurrentLinkedQueue;

public class MainProg
{
  public static void main(String[] args)
  {
    ConcurrentLinkedQueue<ReportData> reportDataQueue = new ConcurrentLinkedQueue<ReportData>();
    ConcurrentLinkedQueue<PageData> pageDataQueue = new ConcurrentLinkedQueue<PageData>();
    ConcurrentLinkedQueue<Page> pageBuffer = new ConcurrentLinkedQueue<Page>();
    ConcurrentLinkedQueue<URL> pageToRetrieveQueue = new ConcurrentLinkedQueue<URL>();
    Stopper stopper = new Stopper();
    DataGatherer gatherer = new DataGatherer(System.currentTimeMillis(),
        pageDataQueue, reportDataQueue);
    Reporter reporter = new Reporter(gatherer, reportDataQueue);
    PageRetriever retriever = new PageRetriever(pageBuffer,
        pageToRetrieveQueue, gatherer, stopper);
    Parser parser = new Parser(pageBuffer, pageToRetrieveQueue, gatherer,
        stopper, pageDataQueue);
    String seedURL = null;
    if (args.length > 0)
      seedURL = args[0];
    boolean correctInfo = false;
    StringBuilder errorMessage = new StringBuilder(
        "There was a problem with your input:\n");
    String thread = "";
    int pages = -1;
    while (!correctInfo)
    {
      Scanner scan = new Scanner(System.in);
      System.out.println("TCSS 422 Webcrawler");
      System.out.print("Single- (S) or Muti- (M - Default)Threaded?>");
      thread = scan.nextLine();
      if (!(thread.equalsIgnoreCase("S") || thread.equalsIgnoreCase("M")))
      {
        correctInfo = false;
        errorMessage.append("--Your thread choice was invalid.\n");
      }
      else
        correctInfo = true;
      System.out
          .print("Maximum Pages to crawl? (Minimum 1, -1 for default of 50)>");
      try
      {
        pages = scan.nextInt();
      }
      catch (InputMismatchException e)
      {
        errorMessage.append("--Page Count was not a valid number");
        correctInfo = false;
      }
      if (pages > 0)
      {
        correctInfo = true;
        gatherer.setPageLimit(pages);
      }
      else if (pages == 0)
      {
        correctInfo = false;
        errorMessage
            .append("--Please select a page count greater than 0 or -1 for the default\n");
      }

      if (!correctInfo)
        System.out.println(errorMessage.append("Please try again")
            .toString());
    }

    try
    {
      URL url = null;
      if (seedURL != null && parser.isValidURL(seedURL))
      {
        url = new URL(seedURL);
      }
      else
      {
        url = new URL("http://faculty.washington.edu/gmobus/");
      }
      pageToRetrieveQueue.add(url);
    }
    catch (MalformedURLException e)
    {
      System.out.println("Bad url");
    }

    switch (thread.toLowerCase().charAt(0))
    {
      case 'm':
        gatherer.setStartTime(System.currentTimeMillis());
        retriever.start();
        parser.start();
        gatherer.start();
        reporter.start();
        break;
      case 's':
        gatherer.setStartTime(System.currentTimeMillis());
        // while less than page limit:
        // retrieve
        // parse
        // report
        boolean goodURL;
        while (gatherer.getPagesRetrieved() < DataGatherer.PAGE_LIMIT)
        {
          goodURL = true;
          URL toGet = pageToRetrieveQueue.poll();
          retriever.getPageContent(toGet);
          Page curPage = pageBuffer.poll();
          long startParseTime = System.currentTimeMillis();
          try
          {
            parser.setDir(curPage.getURL());
            parser.parse(curPage.getContent());
          }
          catch (NullPointerException e)
          {
            goodURL = false;
          }
          if (goodURL)
          {
            PageData pageData = new PageData(curPage.getContent(), System
                .currentTimeMillis()
                - startParseTime, parser.getURLCount());
            gatherer.incrementPageCount();
            gatherer.addToTotalParseTime(pageData.getParseTime());
            gatherer.countWords(pageData.getPageContent());
            gatherer.countKeywords(pageData.getPageContent());
            gatherer.addUrlsCount(pageData.getUrlCount());
            ReportData rd = new ReportData(gatherer.getPagesRetrieved(),
                gatherer.getAvgUrlsPerPage(),
                gatherer.getAvgWordsPerPage(), gatherer
                    .getParseTimePerPage(), gatherer.getStartTime(),
                gatherer.getKeywordData());
            reporter.report(rd);
          }

        }
        break;

      default:
        System.out.println("Couldn't find an option");
    }
  }
}
